package com.dustedpixels.jasmin.chips.z80.implbase;

import com.dustedpixels.jasmin.chips.z80.Z80;

/**
 * A Z80 implementation base.
 */
public abstract class Z80ImplBase implements Z80 {

    public void processUntil(long cycles) {
        while (getCycles() < cycles)
            processInstruction();
    }

    public short getAF() {
        return (short) ((getA() << 8) | (getF() & 0xFF));
    }

    public short getAF2() {
        return (short) ((getA2() << 8) | (getF2() & 0xFF));
    }

    public short getBC() {
        return (short) ((getB() << 8) | (getC() & 0xFF));
    }

    public short getBC2() {
        return (short) ((getB2() << 8) | (getC2() & 0xFF));
    }

    public short getDE() {
        return (short) ((getD() << 8) | (getE() & 0xFF));
    }

    public short getDE2() {
        return (short) ((getD2() << 8) | (getE2() & 0xFF));
    }

    public short getHL() {
        return (short) ((getH() << 8) | (getL() & 0xFF));
    }

    public short getHL2() {
        return (short) ((getH2() << 8) | (getL2() & 0xFF));
    }

    public void setAF(short value) {
        setA((byte) (value >>> 8));
        setF((byte) value);
    }

    public void setAF2(short value) {
        setA2((byte) (value >>> 8));
        setF2((byte) value);
    }

    public void setBC(short value) {
        setB((byte) (value >>> 8));
        setC((byte) value);
    }

    public void setBC2(short value) {
        setB2((byte) (value >>> 8));
        setC2((byte) value);
    }

    public void setDE(short value) {
        setD((byte) (value >>> 8));
        setE((byte) value);
    }

    public void setDE2(short value) {
        setD2((byte) (value >>> 8));
        setE2((byte) value);
    }

    public void setHL(short value) {
        setH((byte) (value >>> 8));
        setL((byte) value);
    }

    public void setHL2(short value) {
        setH2((byte) (value >>> 8));
        setL2((byte) value);
    }

    public boolean getCFlag() {return (getF() & 0x01) != 0;} 
    public boolean getNFlag() {return (getF() & 0x02) != 0;} 
    public boolean getPFlag() {return (getF() & 0x04) != 0;} 
    public boolean getXFlag() {return (getF() & 0x08) != 0;} 
    public boolean getHFlag() {return (getF() & 0x10) != 0;} 
    public boolean getYFlag() {return (getF() & 0x20) != 0;} 
    public boolean getZFlag() {return (getF() & 0x40) != 0;} 
    public boolean getSFlag() {return (getF() & 0x80) != 0;} 

    public void setCFlag(boolean value) {if (value) setF((byte) (getF() | 0x01)); else setF((byte) (getF() & 0xFE));} 
    public void setNFlag(boolean value) {if (value) setF((byte) (getF() | 0x02)); else setF((byte) (getF() & 0xFD));} 
    public void setPFlag(boolean value) {if (value) setF((byte) (getF() | 0x04)); else setF((byte) (getF() & 0xFB));} 
    public void setXFlag(boolean value) {if (value) setF((byte) (getF() | 0x08)); else setF((byte) (getF() & 0xF7));} 
    public void setHFlag(boolean value) {if (value) setF((byte) (getF() | 0x10)); else setF((byte) (getF() & 0xEF));} 
    public void setYFlag(boolean value) {if (value) setF((byte) (getF() | 0x20)); else setF((byte) (getF() & 0xDF));} 
    public void setZFlag(boolean value) {if (value) setF((byte) (getF() | 0x40)); else setF((byte) (getF() & 0xBF));} 
    public void setSFlag(boolean value) {if (value) setF((byte) (getF() | 0x80)); else setF((byte) (getF() & 0x7F));} 
}
